
#include "Callbacks.hpp"
#include "EventLoop.hpp"
#include "TcpServer.hpp"
#include <iostream>
#include <string>

class Server {

  public:
    Server(zephyr::EventLoop *loop, const zephyr::InetAddress &listenAddr, const std::string &name)
        : m_server(loop, listenAddr, name)
        , m_loop(loop) {
        m_server.setConnectionCallback(
            std::bind(&Server::onConnection, this, std::placeholders::_1)
        );
        m_server.setMessageCallback(
            std::bind(&Server::onMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
        );
    }

    void start() {
        m_server.start();
    }

  private:
    void onConnection(const zephyr::TcpConnectionPtr &conn) {
        if (conn->connected()) {
            std::cout << conn->peerAddress().toIpPort() << "->" << conn->localAddress().toIpPort() << "success" << std::endl;
        } else {
            std::cout << conn->peerAddress().toIpPort() << "->" << conn->localAddress().toIpPort() << "failed" << std::endl;
            conn->shutdown();
        }
    }

    void onMessage(const zephyr::TcpConnectionPtr &conn,
                   zephyr::Buffer *buffer,
                   zephyr::Timestamp time) {
        std::string buf = buffer->retrieveAllAsString();
        std::cout << "recv data: " << buf << " time: " << time.toString() << std::endl;
        conn->send(buf);
    }

  private:
    zephyr::TcpServer m_server;
    zephyr::EventLoop *m_loop;
};

int main() {
    std::cout << "Hello muduo_c11 project" << std::endl;
    zephyr::EventLoop loop;
    sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = INADDR_ANY;
    saddr.sin_port = htons(6000);
    zephyr::InetAddress addr(saddr);
    Server server(&loop, addr, "Server");

    server.start();
    loop.loop();

    return 0;
}